package org.nf.web.mapping;

import jakarta.servlet.http.HttpServletRequest;
import org.nf.web.annotation.RequestMapping;
import org.nf.web.config.Configure;
import org.nf.web.servlet.HandlerMapping;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * @author zhu
 * @date 2024-05-15
 */
public class MethodHandlerMapping implements HandlerMapping {

    /**
     * 用于存放匹配的映射方法
     * 保存过滤好的 Controller，key为请求的映射地址，value为 Controller 的 Method 对象
     */
    private Map<String, Method> map = new HashMap<String, Method>();

    @Override
    public Object getHandler(HttpServletRequest request) {
        String uri = request.getRequestURI();
        // 去掉 contextPath 的前缀
        uri = uri.replace(request.getContextPath(),"");
        // 根据请求的uri找到匹配的method对象返回
        return map.get(uri);
    }

    @Override
    public void init(Configure configure) {
        Set<Class<?>> classes = configure.getClasses();
        // 获取所有扫描的类下面的 method 对象
        classes.forEach(clazz -> {
            // 类上声明了注解则作为请求url的前缀
            String prefix = "";
            if (clazz.isAnnotationPresent(RequestMapping.class)) {
                prefix = clazz.getAnnotation(RequestMapping.class).value();
            }
            // 遍历类里面的所有方法，找出带有注解的Method
            Method[] methods = clazz.getMethods();
            for (Method method : methods) {
                if (method.isAnnotationPresent(RequestMapping.class)){
                    // 构建完整的请求地址
                    String uri = prefix + method.getAnnotation(RequestMapping.class).value();
                    // 将uri和method保存搭配map集合中
                    map.put(uri, method);
                }
            }
        });
    }
}
